#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
工具函数模块
Utilities Module

提供FPS计数器、追踪工具等辅助功能
"""

import time
import threading
import logging
from collections import deque
from typing import Tuple, Optional, Dict, Any

logger = logging.getLogger("Utils")


class FPSCounter:
    """FPS计数器"""
    
    def __init__(self, avg_frames: int = 30):
        """
        初始化FPS计数器
        
        Args:
            avg_frames: 用于计算平均FPS的帧数
        """
        self.avg_frames = avg_frames
        self.frame_times = deque(maxlen=avg_frames)
        self.last_time = time.time()
        self.fps = 0.0
        self.lock = threading.Lock()
    
    def update(self) -> float:
        """
        更新FPS计数
        
        Returns:
            float: 当前FPS
        """
        current_time = time.time()
        
        with self.lock:
            self.frame_times.append(current_time - self.last_time)
            self.last_time = current_time
            
            if len(self.frame_times) > 1:
                avg_frame_time = sum(self.frame_times) / len(self.frame_times)
                self.fps = 1.0 / avg_frame_time if avg_frame_time > 0 else 0.0
        
        return self.fps
    
    def get_fps(self) -> float:
        """获取当前FPS"""
        with self.lock:
            return self.fps


class TrackingUtils:
    """追踪工具类"""
    
    @staticmethod
    def calculate_distance(point1: Tuple[int, int], point2: Tuple[int, int]) -> float:
        """
        计算两点之间的距离
        
        Args:
            point1: 第一个点 (x, y)
            point2: 第二个点 (x, y)
            
        Returns:
            float: 距离
        """
        x1, y1 = point1
        x2, y2 = point2
        return ((x2 - x1) ** 2 + (y2 - y1) ** 2) ** 0.5
    
    @staticmethod
    def calculate_direction(offset_x: float, offset_y: float) -> str:
        """
        根据偏移量计算方向
        
        Args:
            offset_x: X轴偏移
            offset_y: Y轴偏移
            
        Returns:
            str: 方向描述
        """
        if abs(offset_x) < 10 and abs(offset_y) < 10:
            return "Center"
        
        direction = ""
        if offset_y < -10:
            direction += "Up"
        elif offset_y > 10:
            direction += "Down"
        
        if offset_x < -10:
            direction += "Left"
        elif offset_x > 10:
            direction += "Right"
        
        return direction if direction else "Center"
    
    @staticmethod
    def is_target_in_center(offset_x: float, offset_y: float, threshold: int = 50) -> bool:
        """
        判断目标是否在中心区域
        
        Args:
            offset_x: X轴偏移
            offset_y: Y轴偏移
            threshold: 中心区域阈值（像素）
            
        Returns:
            bool: 是否在中心区域
        """
        return abs(offset_x) <= threshold and abs(offset_y) <= threshold


class DataStore:
    """线程安全的数据存储"""
    
    def __init__(self):
        """初始化数据存储"""
        self.lock = threading.Lock()
        self._data = {
            'face_detection': {
                'faces': [],
                'face_count': 0,
                'inference_time': 0.0,
                'timestamp': 0.0
            },
            'gimbal_status': {
                'connected': False,
                'pan_angle': 135.0,
                'tilt_angle': 135.0,
                'timestamp': 0.0
            },
            'tracking_status': {
                'enabled': False,
                'target_id': None,
                'target_center': None,
                'offset': None,
                'timestamp': 0.0
            },
            'system_status': {
                'fps': 0.0,
                'total_frames': 0,
                'uptime': 0.0,
                'timestamp': 0.0
            }
        }
    
    def update_face_detection(self, faces: list, inference_time: float):
        """更新人脸检测数据"""
        with self.lock:
            self._data['face_detection'] = {
                'faces': faces.copy() if faces else [],
                'face_count': len(faces) if faces else 0,
                'inference_time': inference_time,
                'timestamp': time.time()
            }
    
    def update_gimbal_status(self, connected: bool, pan_angle: float, tilt_angle: float):
        """更新云台状态"""
        with self.lock:
            self._data['gimbal_status'] = {
                'connected': connected,
                'pan_angle': pan_angle,
                'tilt_angle': tilt_angle,
                'timestamp': time.time()
            }
    
    def update_tracking_status(self, enabled: bool, target_id: Optional[int] = None, 
                             target_center: Optional[Tuple[int, int]] = None,
                             offset: Optional[Tuple[float, float]] = None):
        """更新追踪状态"""
        with self.lock:
            self._data['tracking_status'] = {
                'enabled': enabled,
                'target_id': target_id,
                'target_center': target_center,
                'offset': offset,
                'timestamp': time.time()
            }
    
    def update_system_status(self, fps: float, total_frames: int, uptime: float):
        """更新系统状态"""
        with self.lock:
            self._data['system_status'] = {
                'fps': fps,
                'total_frames': total_frames,
                'uptime': uptime,
                'timestamp': time.time()
            }
    
    def get_face_detection_data(self) -> Dict[str, Any]:
        """获取人脸检测数据"""
        with self.lock:
            return self._data['face_detection'].copy()
    
    def get_gimbal_status(self) -> Dict[str, Any]:
        """获取云台状态"""
        with self.lock:
            return self._data['gimbal_status'].copy()
    
    def get_tracking_status(self) -> Dict[str, Any]:
        """获取追踪状态"""
        with self.lock:
            return self._data['tracking_status'].copy()
    
    def get_system_status(self) -> Dict[str, Any]:
        """获取系统状态"""
        with self.lock:
            return self._data['system_status'].copy()
    
    def get_all_data(self) -> Dict[str, Any]:
        """获取所有数据"""
        with self.lock:
            return {
                'face_detection': self._data['face_detection'].copy(),
                'gimbal_status': self._data['gimbal_status'].copy(),
                'tracking_status': self._data['tracking_status'].copy(),
                'system_status': self._data['system_status'].copy(),
                'timestamp': time.time()
            }


class PerformanceMonitor:
    """性能监控器"""
    
    def __init__(self):
        """初始化性能监控器"""
        self.start_time = time.time()
        self.frame_count = 0
        self.fps_counter = FPSCounter()
        self.lock = threading.Lock()
    
    def update_frame(self):
        """更新帧计数"""
        with self.lock:
            self.frame_count += 1
            self.fps_counter.update()
    
    def get_stats(self) -> Dict[str, Any]:
        """获取性能统计"""
        with self.lock:
            uptime = time.time() - self.start_time
            return {
                'uptime': uptime,
                'total_frames': self.frame_count,
                'current_fps': self.fps_counter.get_fps(),
                'average_fps': self.frame_count / uptime if uptime > 0 else 0.0
            }
